package com.bsj.power.sdk.config.hksdk.alarm;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsj.power.common.config.cached.RedisCached;
import com.bsj.power.common.config.global.JsonResult;
import com.bsj.power.common.config.redis.AlarmConstant;
import com.bsj.power.common.config.rocketmq.producer.BaseMqPushUtil;
import com.bsj.power.common.constant.AlarmEnum;
import com.bsj.power.common.constant.MqTopicAndTagConstants;
import com.bsj.power.common.constant.NumericalConstants;
import com.bsj.power.common.def.entity.alarmReport.AlarmReport;
import com.bsj.power.common.def.entity.gb28181.Device;
import com.bsj.power.common.def.mq.sdk.SdkDevice;
import com.bsj.power.common.def.mq.sdk.SdkLoginDevInfo;
import com.bsj.power.common.def.mq.sdk.face.PersonInfo;
import com.bsj.power.common.def.mq.sdk.face.SdkFaceLoginDevInfo;
import com.bsj.power.common.def.vo.WebSocketMsgVO;
import com.bsj.power.common.util.*;
import com.bsj.power.sdk.cache.ChildDeviceCache;
import com.bsj.power.sdk.cache.ChildFaceDeviceCache;
import com.bsj.power.sdk.cache.VideoChCache;
import com.bsj.power.sdk.config.hksdk.HCNetSDK;
import com.bsj.power.sdk.config.hksdk.HKSDKClientManage;
import com.bsj.power.sdk.config.hksdk.constant.HKSdkConstant;
import com.bsj.power.sdk.config.hksdk.user.UserManage;
import com.bsj.power.sdk.config.hksdk.video.VideoOperate;
import com.bsj.power.sdk.config.hksdk.video.VideoPlayOp;
import com.bsj.power.sdk.service.handle.HKSDKAlarmHandle;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date;

/**
 * @author yinhao
 * @version 1.0
 * @description 报警处理类
 * @date 2024/8/27
 */
@Slf4j
@Component
public class AlarmDataParse {

//    private static HKSDKAlarmHandle hksdkAlarmHandle;
//    static {
//        hksdkAlarmHandle = SpringUtil.getBean(HKSDKAlarmHandle.class);
//    }

    @Autowired
    private BaseMqPushUtil baseMqPushUtil;

    public static void alarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        log.info("报警事件类型： lCommand: {}", Integer.toHexString(lCommand));
        String sTime;
        String MonitoringSiteID;
        HCNetSDK.BYTE_ARRAY byte_array1 = new HCNetSDK.BYTE_ARRAY(25);
        byte_array1.write();
        Pointer pbyte_array1 = byte_array1.getPointer();
        pbyte_array1.write(0, pUser.getByteArray(0, byte_array1.size()), 0, byte_array1.size());
        byte_array1.read();
        Date time = new Date();
        int lUserID = pAlarmer.lUserID;
        HKSDKAlarmHandle hksdkAlarmHandle = SpringUtil.getBean(HKSDKAlarmHandle.class);
        System.out.println(new String(byte_array1.byValue).trim());
        SdkFaceLoginDevInfo sdkFaceLoginDevInfo = ChildFaceDeviceCache.getInfo(lUserID);
        if (sdkFaceLoginDevInfo != null && lCommand == HCNetSDK.COMM_ALARM_ACS) {
            faceDataHandle(pAlarmInfo, pAlarmer, lUserID);
            log.info("获取到面板机设备登录信息：{}", sdkFaceLoginDevInfo);
        } else {
            SdkLoginDevInfo info = ChildDeviceCache.getInfo(lUserID);
            SdkDevice deviceInfo = null;
            if (info != null) {
                deviceInfo = VideoChCache.getDeviceInfo(info.getId());
            }
            if (deviceInfo == null) {
                log.info("未获取到设备信息，不进行附件存储");
                return;
            }
            Device device = deviceInfo.getDevice();
            AlarmReport alarmReport = new AlarmReport();
            alarmReport.setDeviceName(device.getDeviceId());
            alarmReport.setNikeName(device.getNickName());
            // GB28181设备
            alarmReport.setDeviceType(4);
            alarmReport.setBeginTime(time);
            alarmReport.setEndTime(time);
            alarmReport.setLongitude(0d);
            alarmReport.setLatitude(0d);
            ByteBuffer buffers = null;
            byte[] bytes = null;
            switch (lCommand) {
                //异常行为检测信息
                case HCNetSDK.COMM_ALARM_RULE:
                    HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                    strVcaAlarm.write();
                    Pointer pVCAInfo = strVcaAlarm.getPointer();
                    pVCAInfo.write(0, pAlarmInfo.getByteArray(0, strVcaAlarm.size()), 0, strVcaAlarm.size());
                    strVcaAlarm.read();
                    switch (strVcaAlarm.struRuleInfo.wEventTypeEx) {
                        //穿越警戒面 (越界侦测)
                        case 1:
                            log.info("产生越界侦测报警产生");
                            strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_TRAVERSE_PLANE.class);
                            if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
                                buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
                                bytes = new byte[strVcaAlarm.dwPicDataLen];
                                //附件存储路径
                                String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
                                        deviceInfo.getDevice().getId(), buffers, bytes);
                                alarmReport.setFilePath(savePath);
                            }
                            alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_CROSS_BORDER.getCode());
                            alarmReport.setRemark(AlarmEnum.COMM_ALARM_RULE_CROSS_BORDER.getName());
                            break;
                        case 2:
                            log.info("目标进入区域报警发生");
                            strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                            if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
                                buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
                                bytes = new byte[strVcaAlarm.dwPicDataLen];
                                //附件存储路径
                                String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
                                        deviceInfo.getDevice().getId(), buffers, bytes);
                                alarmReport.setFilePath(savePath);
                            }
                            alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_ENTER.getCode());
                            alarmReport.setRemark(AlarmEnum.COMM_ALARM_RULE_ENTER.getName());
                            break;
                        case 3:
                            log.info("目标离开区域报警发生");
                            strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                            //图片保存
                            if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
                                buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
                                bytes = new byte[strVcaAlarm.dwPicDataLen];
                                //附件存储路径
                                String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
                                        deviceInfo.getDevice().getId(), buffers, bytes);
                                alarmReport.setFilePath(savePath);
                            }
                            alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_OUT.getCode());
                            alarmReport.setRemark(AlarmEnum.COMM_ALARM_RULE_OUT.getName());
                            break;
                        case 4:
                            log.info("周界入侵报警发生");
//                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_INTRUSION.class);
//                        //图片保存
//                        if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
//                            buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
//                            bytes = new byte[strVcaAlarm.dwPicDataLen];
//                            //附件存储路径
//                            String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
//                                    deviceInfo.getDevice().getId(), buffers, bytes);
//                            alarmReport.setFilePath(savePath);
//                        }
//                        alarmReport.setAlarmType(AlarmEnum.INTRUSION_DETECTION_ALARM.getCode());
//                        alarmReport.setRemark("异常行为-周界入侵报警");
                            break;
                        case 5:
                            log.info("徘徊报警发生");
//                        alarmReport.setAlarmType(AlarmEnum.WANDERING_DETECTION_ALARM.getCode());
//                        alarmReport.setRemark("异常行为-徘徊报警");
                            break;
                        case 8:
                            log.info("快速移动(奔跑)事件触发");
//                        alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_RUN.getCode());
//                        alarmReport.setRemark("异常行为-快速移动(奔跑)事件触发");
                            break;
                        case 15:
                            log.info("事件触发");
//                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_LEAVE_POSITION.class);
//                        //图片保存
//                        if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
//                            buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
//                            bytes = new byte[strVcaAlarm.dwPicDataLen];
//                            //附件存储路径
//                            String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
//                                    deviceInfo.getDevice().getId(), buffers, bytes);
//                            alarmReport.setFilePath(savePath);
//                        }
//                        alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_EVENT.getCode());
//                        alarmReport.setRemark("异常行为-事件触发");
                            break;
                        case 20:
                            log.info("倒地事件触发");
//                        alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_FALL.getCode());
//                        alarmReport.setRemark("异常行为-倒地事件触发");
                            break;
                        case 44:
                            log.info("玩手机报警发生");
//                        if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
//                            buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
//                            bytes = new byte[strVcaAlarm.dwPicDataLen];
//                            //附件存储路径
//                            String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
//                                    deviceInfo.getDevice().getId(), buffers, bytes);
//                            alarmReport.setFilePath(savePath);
//                        }
//                        alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_WITH_PHONE.getCode());
//                        alarmReport.setRemark("异常行为-玩手机报警发生");
                            break;
                        case 45:
                            log.info("区域入侵发生");
                            if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
                                buffers = strVcaAlarm.pImage.getByteBuffer(0, strVcaAlarm.dwPicDataLen);
                                bytes = new byte[strVcaAlarm.dwPicDataLen];
                                //附件存储路径
                                String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
                                        deviceInfo.getDevice().getId(), buffers, bytes);
                                alarmReport.setFilePath(savePath);
                            } else {
                                //没有系统自带附件就改为自动录像
                                Integer channel = deviceInfo.getCh();
                                if (channel == null) {
                                    log.info("设备通道号未知: {}", deviceInfo);
                                    break;
                                }
                                Integer ch = HKSdkConstant.cvr + channel;
                                String filePath = FileCreateUtil.filePathFormat(time, HKSdkConstant.annexPath,
                                        4, device.getId(), ".mp4");
                                String start = DateUtils.dateToStr(new Date(time.getTime() - 30000));
                                String end = DateUtils.dateToStr(time);
                                SdkLoginDevInfo cvrDevInfo = HKSDKClientManage.crvSdkDev.get(deviceInfo.getCvrName());
                                VideoOperate.downloadRecordByTime(cvrDevInfo.getUserId(), ch,
                                        start, end, HKSdkConstant.annexPath + filePath);
                                alarmReport.setFilePath(filePath);
                            }
                            alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_RULE_ENTER_AREA.getCode());
                            alarmReport.setRemark(AlarmEnum.COMM_ALARM_RULE_ENTER_AREA.getName());
                            break;
                        default:
                            log.info("行为事件类型: {}", strVcaAlarm.struRuleInfo.wEventTypeEx);
//                        String commRuleType = "1102" +  strVcaAlarm.struRuleInfo.wEventTypeEx;
//                        alarmReport.setAlarmType(Integer.parseInt(commRuleType));
//                        alarmReport.setRemark("异常行为-行为事件类型: " + commRuleType);
                            break;
                    }
                    break;
                //移动侦测、视频丢失、遮挡、IO信号量等报警信息(V3.0以上版本支持的设备)
                case HCNetSDK.COMM_ALARM_V30:
                    HCNetSDK.NET_DVR_ALARMINFO_V30 struAlarmInfo = new HCNetSDK.NET_DVR_ALARMINFO_V30();
                    struAlarmInfo.write();
                    Pointer pAlarmInfo_V30 = struAlarmInfo.getPointer();
                    pAlarmInfo_V30.write(0, pAlarmInfo.getByteArray(0, struAlarmInfo.size()), 0, struAlarmInfo.size());
                    struAlarmInfo.read();
                    log.info("V30报警类型：{}", struAlarmInfo.dwAlarmType);
                    RedisCached redisCached = SpringUtil.getBean(RedisCached.class);
                    switch (struAlarmInfo.dwAlarmType) {
                        //移动侦测
                        case 3:
                            log.info("V30移动侦测报警产生");
                            String s = redisCached.get(AlarmConstant.ALARM_V30_MOVE_TEMP_KEY + device.getDeviceId());
                            if (StringUtils.isEmpty(s)) {
                                //移动侦测不会产生附件,采用系统调用视频自动抓图
                                String filePath = FileCreateUtil.filePathFormat(time, HKSdkConstant.annexPath,
                                        4, device.getId(), ".jpg");
                                VideoPlayOp.realPlay(lUserID, 1, HKSdkConstant.annexPath, filePath);
                                alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_V30_MOVE.getCode());
                                alarmReport.setFilePath(filePath);
                                //3是移动侦测报警
                                alarmReport.setRemark(AlarmEnum.COMM_ALARM_V30_MOVE.getName());
                                redisCached.set(AlarmConstant.ALARM_V30_MOVE_TEMP_KEY + device.getDeviceId(),
                                        JSON.toJSONString(alarmReport), 3 * 60);
                            }
                            break;
                        //遮挡报警
                        case 6:
                            log.info("V30视频遮挡报警产生");
                            String out = redisCached.get(AlarmConstant.ALARM_V30_BLOCK_OUT_TEMP_KEY + device.getDeviceId());
                            if (StringUtils.isEmpty(out)) {
                                alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_V40_BLOCK_OUT.getCode());
                                //6是遮挡报警
                                alarmReport.setRemark(AlarmEnum.COMM_ALARM_V40_BLOCK_OUT.getName());
                                redisCached.set(AlarmConstant.ALARM_V30_BLOCK_OUT_TEMP_KEY + device.getDeviceId(),
                                        JSON.toJSONString(alarmReport), 3 * 60);
                            }
                            break;
                    }
                    break;
                //移动侦测、视频丢失、遮挡、IO信号量等报警信息，报警数据为可变长
                case HCNetSDK.COMM_ALARM_V40:
                    HCNetSDK.NET_DVR_ALARMINFO_V40 struAlarmInfoV40 = new HCNetSDK.NET_DVR_ALARMINFO_V40();
                    struAlarmInfoV40.write();
                    Pointer pAlarmInfoV40 = struAlarmInfoV40.getPointer();
                    pAlarmInfoV40.write(0, pAlarmInfo.getByteArray(0, struAlarmInfoV40.size()), 0, struAlarmInfoV40.size());
                    struAlarmInfoV40.read();
                    switch (struAlarmInfoV40.struAlarmFixedHeader.dwAlarmType) {
                        case 1:
                            log.info("硬盘满");
//                        alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_V40_DRIVE_FULL.getCode());
//                        alarmReport.setRemark("硬盘满报警");
                            break;
                        case 2:
                            log.info("信号丢失报警");
//                        alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_V40_NO_SIGNAL.getCode());
//                        alarmReport.setRemark("信号丢失报警");
                            break;
                        case 6:
                            log.info("遮挡报警");
                            alarmReport.setAlarmType(AlarmEnum.COMM_ALARM_V40_BLOCK_OUT.getCode());
                            alarmReport.setRemark(AlarmEnum.COMM_ALARM_V40_BLOCK_OUT.getName());
                            break;
                        default:
                            log.info("移动侦测、视频丢失、遮挡、IO信号量等报警信息");
//                        String commRuleType = "4007" + struAlarmInfoV40.struAlarmFixedHeader.dwAlarmType;
//                        alarmReport.setAlarmType(Integer.parseInt(commRuleType));
//                        alarmReport.setRemark("移动侦测、视频丢失、遮挡、IO信号量等报警信息");
                            break;
                    }
                    //温度报警信息
                case HCNetSDK.COMM_THERMOMETRY_ALARM:
                    HCNetSDK.NET_DVR_THERMOMETRY_ALARM struTemInfo = new HCNetSDK.NET_DVR_THERMOMETRY_ALARM();
                    struTemInfo.write();
                    Pointer pTemInfo = struTemInfo.getPointer();
                    pTemInfo.write(0, pAlarmInfo.getByteArray(0, struTemInfo.size()), 0, struTemInfo.size());
                    struTemInfo.read();
                    String sThermAlarmInfo = "规则ID:" + struTemInfo.byRuleID + "预置点号：" + struTemInfo.wPresetNo + "报警等级：" + struTemInfo.byAlarmLevel + "报警类型：" +
                            struTemInfo.byAlarmType + "当前温度：" + struTemInfo.fCurrTemperature;
                    log.info("温度报警信息: {}", sThermAlarmInfo);
                    //可见光图片保存
//                if ((struTemInfo.dwPicLen > 0) && (struTemInfo.byPicTransType == 0)) {
//                    buffers = struTemInfo.pPicBuff.getByteBuffer(0, struTemInfo.dwPicLen);
//                    bytes = new byte[struTemInfo.dwPicLen];
//                    //附件存储路径
//                    String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
//                            deviceInfo.getDevice().getId(), buffers, bytes);
//                    alarmReport.setFilePath(savePath);
//                }
//                alarmReport.setAlarmType(AlarmEnum.COMM_THERMOMETRY_ALARM_TEMPERATURE.getCode());
//                alarmReport.setRemark(sThermAlarmInfo);
                    break;
                //温差检测报警
                case HCNetSDK.COMM_THERMOMETRY_DIFF_ALARM:
                    HCNetSDK.NET_DVR_THERMOMETRY_DIFF_ALARM strThermDiffAlarm = new HCNetSDK.NET_DVR_THERMOMETRY_DIFF_ALARM();
                    strThermDiffAlarm.write();
                    Pointer pTemDiffInfo = strThermDiffAlarm.getPointer();
                    pTemDiffInfo.write(0, pAlarmInfo.getByteArray(0, strThermDiffAlarm.size()), 0, strThermDiffAlarm.size());
                    strThermDiffAlarm.read();
                    String sThremDiffInfo = "通道号：" + strThermDiffAlarm.dwChannel + ",报警规则：" + strThermDiffAlarm.byAlarmRule
                            + "，当前温差：" + strThermDiffAlarm.fCurTemperatureDiff;
                    log.info("温差检测报警: {}", sThremDiffInfo);
                    //可见光图片保存
//                if ((strThermDiffAlarm.dwPicLen > 0) && (strThermDiffAlarm.byPicTransType == 0)) {
//                    buffers = strThermDiffAlarm.pPicBuff.getByteBuffer(0, strThermDiffAlarm.dwPicLen);
//                    bytes = new byte[strThermDiffAlarm.dwPicLen];
//                    //附件存储路径
//                    String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
//                            deviceInfo.getDevice().getId(), buffers, bytes);
//                    alarmReport.setFilePath(savePath);
//                }
//                alarmReport.setAlarmType(AlarmEnum.COMM_THERMOMETRY_ALARM_TEMP_RANGE.getCode());
//                alarmReport.setRemark(sThremDiffInfo);
                    break;
                //烟火检测
                case HCNetSDK.COMM_FIREDETECTION_ALARM:
                    HCNetSDK.NET_DVR_FIREDETECTION_ALARM struFireDecAlarm = new HCNetSDK.NET_DVR_FIREDETECTION_ALARM();
                    struFireDecAlarm.write();
                    Pointer pFireDecAlarm = struFireDecAlarm.getPointer();
                    pFireDecAlarm.write(0, pAlarmInfo.getByteArray(0, struFireDecAlarm.size()), 0, struFireDecAlarm.size());
                    struFireDecAlarm.read();
                    String sFireDecAlarmInfo = "绝对时间：" + struFireDecAlarm.dwAbsTime + ",报警子类型：" + struFireDecAlarm.byAlarmSubType + ",火点最高温度 :" +
                            struFireDecAlarm.wFireMaxTemperature + ",火点目标距离：" + struFireDecAlarm.wTargetDistance;
                    log.info("烟火报警检测: {}", sFireDecAlarmInfo);
                    //可见光图片保存
//                if ((struFireDecAlarm.dwVisiblePicLen > 0) && (struFireDecAlarm.byPicTransType == 0)) {
//                    buffers = struFireDecAlarm.pVisiblePicBuf.getByteBuffer(0, struFireDecAlarm.dwVisiblePicLen);
//                    bytes = new byte[struFireDecAlarm.dwVisiblePicLen];
//                    //附件存储路径
//                    String savePath = saveAlarmAnnex(time, HKSdkConstant.annexPath,
//                            deviceInfo.getDevice().getId(), buffers, bytes);
//                    alarmReport.setFilePath(savePath);
//                }
//                alarmReport.setAlarmType(AlarmEnum.COMM_FIRE_DETECTION_ALARM.getCode());
//                alarmReport.setRemark(sFireDecAlarmInfo);
                    break;
                //AI开放平台接入视频检测报警信息
                case HCNetSDK.COMM_UPLOAD_AIOP_VIDEO:
                    log.info("AI开放平台接入视频检测报警上传");
                    HCNetSDK.NET_AIOP_VIDEO_HEAD struAIOPVideo = new HCNetSDK.NET_AIOP_VIDEO_HEAD();
                    struAIOPVideo.write();
                    Pointer pAIOPVideo = struAIOPVideo.getPointer();
                    pAIOPVideo.write(0, pAlarmInfo.getByteArray(0, struAIOPVideo.size()), 0, struAIOPVideo.size());
                    struAIOPVideo.read();
                    log.info("视频任务ID: {}, 通道号：{}, 检测模型包ID: {}",
                            new String(struAIOPVideo.szTaskID), struAIOPVideo.dwChannel, new String(struAIOPVideo.szMPID));
                    if (struAIOPVideo.dwAIOPDataSize > 0) {
//                    dwAIOPData(struAIOPVideo, time, HKSdkConstant.annexPath,
//                            deviceInfo.getDevice().getId(), ".json", 1);
                        buffers = struAIOPVideo.pBufferAIOPData.getByteBuffer(0, struAIOPVideo.dwAIOPDataSize);
                        bytes = new byte[struAIOPVideo.dwAIOPDataSize];
                        buffers.rewind();
                        buffers.get(bytes);
                        String aiAlarmJsonStr = new String(bytes);
                        log.info("AI报警信息: {}", aiAlarmJsonStr);
                        JSONObject aiObject = JSON.parseObject(aiAlarmJsonStr);
                        //1005: 安全帽检测事件 1003:人员姿态检测事件
                        Integer aitype = aiObject.getInteger("aitype");
                        if (aitype != null) {
                            JSONArray aiJsonArr = aiObject.getJSONArray("targets");
                            JSONObject events = aiObject.getJSONObject("events");
                            JSONArray alertInfoArr = events.getJSONArray("alertInfo");
                            JSONObject alertObj = alertInfoArr.getJSONObject(0);
                            JSONObject ruleInfo = alertObj.getJSONObject("ruleInfo");
                            //AI事件的规则名称
                            String ruleName = ruleInfo.getString("ruleName");
                            switch (aitype) {
                                case 1003:
                                    alarmReport.setAlarmType(AlarmEnum.AI_FACE_ALARM_LIE.getCode());
                                    alarmReport.setRemark(AlarmEnum.AI_FACE_ALARM_LIE.getName());
                                    break;
                                case 1005:
//                                JSONArray propertiesArr = targetsObj.getJSONArray("properties");
//                                JSONObject propertiesObj = propertiesArr.getJSONObject(0);
//                                JSONObject classify = propertiesObj.getJSONObject("classify");
//                                //0 未戴安全帽
//                                Integer attrType = classify.getInteger("attrType");
//                                Integer attrValue = classify.getInteger("attrValue");
                                    if (ruleName.contains("安全帽")) {
                                        alarmReport.setAlarmType(AlarmEnum.AI_FACE_ALARM.getCode());
                                        alarmReport.setRemark("AI人脸检测未佩戴安全帽");
                                    } else if (ruleName.contains("安全绳")) {
                                        alarmReport.setAlarmType(AlarmEnum.AI_FACE_ALARM_SAFETY_ROPE.getCode());
                                        alarmReport.setRemark(AlarmEnum.AI_FACE_ALARM_SAFETY_ROPE.getName());
                                    }
                                    break;
                                default:
                                    log.warn("未检测的AI包事件类型: {}", aitype);
                                    break;
                            }
                        }
                    }
                    if (struAIOPVideo.dwPictureSize > 0) {
                        String dwJpgPath = dwAIOPData(struAIOPVideo, time, HKSdkConstant.annexPath,
                                deviceInfo.getDevice().getId(), ".jpg", 2);
                        alarmReport.setFilePath(dwJpgPath);
                    }
                    break;
                default:
                    log.warn("其他报警未处理");
//                String hexString = Integer.toHexString(lCommand);
//                alarmReport.setAlarmType(Integer.parseInt(hexString));
//                alarmReport.setRemark("其他报警: " + hexString);
                    break;
            }
            try {
                if (alarmReport.getAlarmType() != null) {
                    hksdkAlarmHandle.doPushObj(alarmReport);
                }
            } catch (Exception e) {
                log.error("报警入库失败：{}", ExceptionUtil.getStackStr(e));
            }
        }

    }

    /**
     * 人脸认证成功处理（门禁主机报警信息）
     *
     * @param pAlarmInfo
     * @return void
     * @author ljx
     * @time 2024/12/31 10:30
     */
    private static void faceDataHandle(Pointer pAlarmInfo, HCNetSDK.NET_DVR_ALARMER pAlarmer, int lUserID) {
        HCNetSDK.NET_DVR_ACS_ALARM_INFO strACSInfo = new HCNetSDK.NET_DVR_ACS_ALARM_INFO();
        strACSInfo.write();
        Pointer pACSInfo = strACSInfo.getPointer();
        pACSInfo.write(0, pAlarmInfo.getByteArray(0, strACSInfo.size()), 0, strACSInfo.size());
        strACSInfo.read();
        //TODO 可能是此处
        /**门禁事件的详细信息解析，通过主次类型的可以判断当前的具体门禁类型，例如（主类型：0X5 次类型：0x4b 表示人脸认证通过，
         主类型：0X5 次类型：0x4c 表示人脸认证失败）*/
//        log.info("序列号是否有效：{}，设备名字是否有效：{}，login端口是否有效：{}，设备IP是否有效：{}，socketIp是否有效：{}，" +
//                        "序列号：{}，设备名字：{}，IP地址：{}，报警主动上传时的socketIP地址，IP协议 0-IPV4 1-IPV6：{}",
//                pAlarmer.bySerialValid, pAlarmer.byDeviceNameValid, pAlarmer.byLinkPortValid, pAlarmer.byDeviceIPValid,
//                pAlarmer.bySocketIPValid, sSerialNumber, new String(pAlarmer.sDeviceName).trim(),
//                new String(pAlarmer.sDeviceIP).trim(), new String(pAlarmer.sSocketIP).trim(), pAlarmer.byIpProtocol);
        //主类型：0X5 次类型：0x4b 表示人脸认证通过
        if (strACSInfo.dwMajor == 0X5 && strACSInfo.dwMinor == 0x4b) {
            String byEmployeeNo = null;
            String byDeviceName = null;
            //pAcsEventInfoExtend是否有效：0-无效，1-有效
            if (strACSInfo.byAcsEventInfoExtend == 1) {
                HCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND strAcsInfoEx = new HCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND();
                strAcsInfoEx.write();
                Pointer pAcsInfoEx = strAcsInfoEx.getPointer();
                pAcsInfoEx.write(0, strACSInfo.pAcsEventInfoExtend.getByteArray(0, strAcsInfoEx.size()), 0, strAcsInfoEx.size());
                strAcsInfoEx.read();
                byEmployeeNo = new String(strAcsInfoEx.byEmployeeNo).trim();
                byDeviceName = new String(strAcsInfoEx.byDeviceName).trim();
            }
            //设备序列号
            String sSerialNumber = new String(pAlarmer.sSerialNumber).trim();
            log.info("接收到人脸认证成功报警，报警主类型：{}，报警次类型：{}，卡号：{}，工号1dwEmployeeNo：{}，工号2byEmployeeNo：{}，时间：{}-{}-{} {}:{}:{}，读卡器编号：{}，" +
                            "门编号：{}，事件触发器编号：{}，设备编号：{}，设备编号原数据：{},byAcsEventInfoExtend：{}，设备序列号：{}，设备基本信息体内的设备序列号：{}"
                    , Integer.toHexString(strACSInfo.dwMajor), Integer.toHexString(strACSInfo.dwMinor), new String(strACSInfo.struAcsEventInfo.byCardNo).trim(),
                    strACSInfo.struAcsEventInfo.dwEmployeeNo, byEmployeeNo, strACSInfo.struTime.dwYear, strACSInfo.struTime.dwMonth,
                    strACSInfo.struTime.dwDay, strACSInfo.struTime.dwHour, strACSInfo.struTime.dwMinute, strACSInfo.struTime.dwSecond,
                    strACSInfo.struAcsEventInfo.dwCardReaderNo, strACSInfo.struAcsEventInfo.dwDoorNo, strACSInfo.struAcsEventInfo.dwCaseSensorNo,
                    String.valueOf(strACSInfo.struAcsEventInfo.byDeviceNo), strACSInfo.struAcsEventInfo.byDeviceNo, strACSInfo.byAcsEventInfoExtend, byDeviceName, sSerialNumber);
            if (StringUtils.isNotBlank(byEmployeeNo)) {
                //查询人员信息
                String str = UserManage.getUserByEmployeeNo(lUserID, byEmployeeNo);
                //解析数据
                if (StringUtils.isNotBlank(str)) {
                    JSONObject jsonObject = JSONObject.parseObject(str);
                    JSONObject userInfoSearch = jsonObject.getJSONObject("UserInfoSearch");
                    JSONArray jsonArray = userInfoSearch.getJSONArray("UserInfo");
                    if (!CollectionUtils.isEmpty(jsonArray)) {
                        JSONObject jsonData = (JSONObject) jsonArray.get(NumericalConstants.ZERO);
                        String employeeNo = jsonData.getString("employeeNo");
                        String name = jsonData.getString("name");
                        if (StringUtils.isAnyBlank(employeeNo, name)) {
                            log.info("工号或姓名为空不弹卡，工号：{}，姓名：{}", employeeNo, name);
                        } else {
                            PersonInfo personInfo = new PersonInfo(employeeNo, name);
                            log.info("人脸识别后根据人员编号查询出来的人员信息：{}", personInfo);
                            if (StringUtils.isNotBlank(sSerialNumber)) {
                                personInfo.setSrcIndex(sSerialNumber);
                                BaseMqPushUtil baseMqPushUtil = SpringUtil.getBean(BaseMqPushUtil.class);
                                baseMqPushUtil.sendTopicBytes(MqTopicAndTagConstants.BASE_SERVER_PLS_FACE_TOPIC,
                                        MqTopicAndTagConstants.BASE_CHANGE_PLS_FACE_TAG, JSON.toJSONBytes(personInfo));
                                log.info("mq消息已发送");
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 创建文件
     *
     * @param struAIOPVideo
     * @param time
     * @param path
     * @param devId
     * @param format
     * @param dataType      1:json内容 2:图片
     */
    private static String dwAIOPData(HCNetSDK.NET_AIOP_VIDEO_HEAD struAIOPVideo,
                                     Date time, String path, Long devId,
                                     String format, Integer dataType) {
        FileOutputStream fout = null;
        try {
            //文件
            String filePath = FileCreateUtil.filePathFormat(time, path, 5, devId, format);
            //文件路径前缀 + 后缀 + 文件名
            String filename = path + filePath;
            fout = new FileOutputStream(filename);
            //将字节写入文件
            long offset = 0;
            ByteBuffer buffers;
            byte[] bytes;
            if (dataType == 1) {
                //json文件
                buffers = struAIOPVideo.pBufferAIOPData.getByteBuffer(offset, struAIOPVideo.dwAIOPDataSize);
                bytes = new byte[struAIOPVideo.dwAIOPDataSize];
            } else {
                //图片
                buffers = struAIOPVideo.pBufferPicture.getByteBuffer(offset, struAIOPVideo.dwPictureSize);
                bytes = new byte[struAIOPVideo.dwPictureSize];
            }
            buffers.rewind();
            buffers.get(bytes);
            fout.write(bytes);
            fout.close();
//            if (dataType == 1) {
//                log.info("AI报警信息: {}", new String(bytes));
//            }
            return filePath;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (fout != null) {
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 保存报警附件并返回路径
     *
     * @param time
     * @param path
     * @param devId
     * @param buffers
     * @param bytes
     * @return
     */
    private static String saveAlarmAnnex(Date time, String path, Long devId,
                                         ByteBuffer buffers, byte[] bytes) {
        FileOutputStream fout = null;
        try {
            //文件
            String filePath = FileCreateUtil.filePathFormat(time, path, 4, devId, ".jpg");
            //文件路径前缀 + 后缀 + 文件名
            String filename = path + filePath;
            fout = new FileOutputStream(filename);
            //将字节写入文件
            buffers.rewind();
            buffers.get(bytes);
            fout.write(bytes);
            fout.close();
            return filePath;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (fout != null) {
                try {
                    fout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
